package com.yp.infrastructure.demo

import com.yp.infrastructure.demo.exception.EnumErrorMessage
import com.yp.infrastructure.demo.exception.PartnerException
import com.yp.infrastructure.demo.model.EnumPartnerType
import org.axonframework.commandhandling.CommandHandler
import org.axonframework.eventhandling.DisallowReplay
import org.axonframework.eventsourcing.EventSourcingHandler
import org.axonframework.modelling.command.AggregateIdentifier
import org.axonframework.modelling.command.AggregateLifecycle
import org.axonframework.modelling.command.AggregateMember
import org.axonframework.spring.stereotype.Aggregate
import org.slf4j.Logger
import org.slf4j.LoggerFactory


@Aggregate
class PartnerAggregate constructor()  {

    val log: Logger = LoggerFactory.getLogger(PartnerAggregate::class.java)

    @AggregateIdentifier
    lateinit var id: String
    lateinit var code: String
    lateinit var name: String

    @AggregateMember
    var customers: MutableSet<String> = mutableSetOf()

    @AggregateMember
    var vendors: MutableSet<String> = mutableSetOf()

    @CommandHandler
    constructor(cmd: CreatePartnerCommand) : this() {
        val e = CreatePartnerEvent(cmd.code, cmd.name, cmd.owner, cmd.type)
        e.id = cmd.id
        AggregateLifecycle.apply(e)
    }


    @EventSourcingHandler
    @DisallowReplay
    fun on(e: CreatePartnerEvent) {
        log.debug("....")
        this.id = e.id
        this.code = e.code
        this.name = e.name
        when (e.type) {
            EnumPartnerType.CUSTOMER -> {
                if (customers.contains(e.owner)) throw PartnerException(
                    EnumErrorMessage.CUSTOMER_EXISTS
                )
                customers.add(e.owner)
            }
            EnumPartnerType.VENDOR -> {
                if (customers.contains(e.owner)) throw PartnerException(
                    EnumErrorMessage.VENDOR_EXISTS
                )
                vendors.add(e.owner)
            }
            else -> {
                throw PartnerException(EnumErrorMessage.UNKNOWN_PARTNER_TYPE)
            }
        }
    }


}